﻿#ifndef LEVELSCANNINGFLOWSESSION_H
#define LEVELSCANNINGFLOWSESSION_H
#include "itestflow.h"
#include <QThread>
#include "3rdparty/includes/receivers/receiver/ireceiver.h"
#include "model/deviceinstancemanager.h"
#include "3rdparty/includes/deviceio/ideviceio.h"

class ScanDataParser;
struct LevelScanningFlowSession : public TestFlowSession {
    DeviceHandle<IDeviceIO> receiverIO;
    DeviceHandle<IReceiver> receiver;

    bool rfMuted = true; //设置静默
    void safeMuteAllOutputs() override;
    bool ensureOutputsEnabled() override;
    bool init();
    bool initReceiver();

    void closeAll() override;
};

class LevelScanningFlow : public ITestFlow
{
public:
    QString name() const override { return "LevelScan"; }

    bool ensureSessionsForSubrange(const Exec::Subrange &subrange,
                                   TestFlowSessionPtr reuseCandidate,
                                   TestFlowSessionPtr &outSession,
                                   TestFlowCallbacks callbacks,
                                   QString &errorMessage) override;

    void safeMuteAllOutputs(const TestFlowSessionPtr &session) override;

    bool measureOnePoint(const Exec::Subrange &subrange,
                         int frequencyIndex,
                         const TestFlowSessionPtr &session,
                         TestFlowCallbacks callbacks,
                         QString &errorMessage) override;
    bool measureLevelScanning(TestFlowCallbacks callbacks,
                              const LevelScanningConfig &config,
                              QString &errorMessage);

    void setPlanOptions(const FlowPlanOptions &opts) override;
    bool buildFrequencyAndLevelArrays(const HardwareTemplateType type, Exec::CurvePtr &factors,
                                      const double safetyMargin, const QString &traceDataString,
                                      QVector<double> &frequenciesHz, QVector<double> &levels);

private:
    FlowPlanOptions options_;
};
struct ScanResult {
    quint32 rawTraceStatus = 0;
    int scanRangeNumber = 0;
    bool isLastBlockOfRange = false;
    bool isLastBlockOfLastRange = false;
    bool isLastOfAllBlocks = false;
    quint32 numberOfPoints = 0;
    QVector<bool> traceActive;
    QVector<QVector<float>> traceData;
    QVector<quint8> statusBytes;

    ScanResult()
    {
        traceActive.resize(6);
        traceData.resize(6);
    }

    void parseTraceStatus()
    {
        scanRangeNumber = rawTraceStatus & 0x3FF;
        quint32 highPart = (rawTraceStatus >> 16) & 0xFFFF;
        if (highPart > 0) {
            scanRangeNumber += highPart;
        }
        isLastBlockOfRange = (rawTraceStatus >> 10) & 1;
        isLastBlockOfLastRange = (rawTraceStatus >> 11) & 1;
        isLastOfAllBlocks = (rawTraceStatus >> 12) & 1;
    }
};

class ScanDataParser : public QObject
{
    Q_OBJECT

public:
    explicit ScanDataParser(QObject *parent = nullptr);

    // 接收从socket读取的数据，并将其添加到内部缓冲区
    bool appendData(const QByteArray &newData, ScanResult &result);

    // 尝试从缓冲区中解析一个完整的数据包。
    // 如果成功，返回true，并将结果填充到result参数中。
    // 如果缓冲区中没有完整的数据包，返回false。
    bool tryParseNextPacket(ScanResult &result);
    void clearBuffer();

signals:
    // 当一个完整的数据包被成功解析时，可以发射此信号
    void packetParsed(const ScanResult &result);

private:
    // 内部缓冲区，用于存储不完整的数据
    QByteArray m_buffer;

    // 内部解析函数，只处理一个完整的数据包
    bool parseCompletePacket(const QByteArray &packet, ScanResult &result);
};
#endif // LEVELSCANNINGFLOWSESSION_H
